package com.zytlifeservice.service.pay;

import com.qianmi.open.api.ApiException;
import com.qianmi.open.api.domain.elife.TrainSeat;
import com.qianmi.open.api.domain.elife.Trainline;
import com.qianmi.open.api.request.*;
import com.qianmi.open.api.response.*;
import com.zytlifeservice.domain.Result;
import com.zytlifeservice.domain.User;
import com.zytlifeservice.domain.pay.*;
import com.zytlifeservice.exception.UserException;
import com.zytlifeservice.repository.UserRepository;
import com.zytlifeservice.repository.pay.AlipayOrderRepository;
import com.zytlifeservice.repository.pay.PassengersRepository;
import com.zytlifeservice.repository.pay.TrainRechargeOrderRepository;
import com.zytlifeservice.repository.pay.WxPayOrderRepository;
import com.zytlifeservice.util.Base64Utils;
import com.zytlifeservice.util.ResultUtil;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.transaction.Transactional;
import java.util.*;

/**
 * 火车票业务类
 * Created by Administrator on 2017/6/3.
 */
@Service
public class TrainService {

    private static final Logger logger = LoggerFactory.getLogger(TrainService.class);

    @Autowired
    PublicService publicService;

    @Autowired
    UserRepository userRepository;

    @Autowired
    AlipayOrderRepository alipayOrderRepository;

    @Autowired
    TrainRechargeOrderRepository trainRechargeOrderRepository;

    @Autowired
    PassengersRepository passengersRepository;

    @Autowired
    AlipayService alipayService;

    @Autowired
    WxPayOrderRepository wxPayOrderRepository;

    @Autowired
    WxPayService wxPayService;

    /*
    查询火车列表信息
     */
    public Result findbyTrainList(String from, String date, String to) throws Exception {
        TrainLinesListRequest req = new TrainLinesListRequest();
        req.setDate(date);
        req.setFrom(from);
        req.setTo(to);
        TrainLinesListResponse response = publicService.execute(req);
        List<Map<String, Object>> trainList = new ArrayList<Map<String, Object>>();
        Map<String, Object> trainMap = null;
        String itemId = findItemId();
        if (null != response.getTrainlines() && response.getTrainlines().size() > 0) {
            List<Trainline> trains = response.getTrainlines();
            for (int i = 0; i < trains.size(); i++) {
                List<TrainSeat> trainSeats = trains.get(i).getTrainSeats();
                if (trainSeats == null || trainSeats.size() == 0) {  //筛选座位，为空时表示当前不可用，过滤掉。
                    continue;
                }
                trainMap = new HashMap<String, Object>();
                trainMap.put("itemIdTrain", itemId);
                trainMap.put("currentStartStationName", trains.get(i).getCurrentStartStationName());
                trainMap.put("endTime", trains.get(i).getEndTime());
                trainMap.put("currentEndStationName", trains.get(i).getCurrentEndStationName());
                trainMap.put("startTime", trains.get(i).getStartTime());
                trainMap.put("trainNumber", trains.get(i).getTrainNumber());
                trainMap.put("trainTypeName", trains.get(i).getTrainTypeName());
                trainMap.put("runTime", trains.get(i).getRunTime());
                trainMap.put("trainSeat", trains.get(i).getTrainSeats());
                trainList.add(trainMap);
            }
            return ResultUtil.success(trainList, "成功");
        } else {
            return ResultUtil.error(-1, "未获取到数据");
        }
    }

    public String findItemId() throws Exception {
        TrainItemsListRequest req = new TrainItemsListRequest();
        TrainItemsListResponse response = publicService.execute(req);
        return response.getItems().get(0).getItemId();
    }

    /*
    火车票下订单
     */
    public TrianRechargeOrder queryInfo(String subject, Long userId, String from, String to, String date,
                                        String trainNumber, String contactName, String contactTel, String passagers,
                                        String itemIdTrain, String startTime, String endTime) throws ApiException {

        User one = userRepository.findOne(userId);
        if (one == null) {
            throw new UserException("用户不存在", 104);
        }
        TrainOrderCreateRequest req = new TrainOrderCreateRequest();
        req.setFrom(from);
        req.setTo(to);
        req.setDate(date);
        req.setTrainNumber(trainNumber);
        req.setStartTime(startTime);
        req.setContactName(contactName);
        req.setContactTel(contactTel);
        req.setItemIdTrain(itemIdTrain);

        //解析乘客信息
        int count = 0;
        StringBuffer sb = new StringBuffer();
        try {
            System.out.println("jsonData=" + passagers);
            JSONObject jsonObject = new JSONObject(passagers);
            JSONArray jsonArray = jsonObject.getJSONArray("data");
            JSONObject jsonObject1 = null;
            for (int i = 0; i < jsonArray.length(); i++) {
                jsonObject1 = new JSONObject();
                jsonObject1 = jsonArray.getJSONObject(i);
                String phone = jsonObject1.getString("phone");
                String name = jsonObject1.getString("name");
                String id =jsonObject1.getString("ID");
                String seatType = jsonObject1.getString("seatType");
                sb.append(name + "," + phone + "," + id + "," + seatType);
                if (count >= 1) {
                    sb.append(";");
                }
                count++;
            }
        } catch (JSONException e) {
            e.printStackTrace();
        }
        req.setPassagers(sb.toString());

        TrainOrderCreateResponse response = publicService.execute(req);
        if (!response.isSuccess()) {
            throw new UserException("火车票预定失败", 303);
        }

        //生成阿里订单
        AlipayOrder alipayOrder = new AlipayOrder();
        alipayOrder.setStoreId(one.getStoreId());
        alipayOrder.setSubject(subject);//对应的后台的信息
        String outTradeNo = "zyt" + userId + System.currentTimeMillis()   //添加userId
                + (long) (Math.random() * 10000000L);
        alipayOrder.setOutTradeNo(outTradeNo);
        System.out.println(response.getTicketTrade().getTotalPayCash());
        alipayOrder.setTotalAmount(response.getTicketTrade().getTotalPayCash());
        alipayOrder.setUserId(userId);
        alipayOrder.setType(AlipayOrder.TYPE_TRAIN);
        alipayOrder.setOrderStatus(AlipayOrder.ORDER_WAIT);
        alipayOrderRepository.save(alipayOrder);

        //生成微信订单
        WxPayOrder wxPayOrder = publicService.generateWxpayOrder(one, subject, "",
                response.getTicketTrade().getTotalPayCash(), outTradeNo, WxPayOrder.TYPE_TRAIN);
        wxPayOrderRepository.save(wxPayOrder);
        logger.info("outTradeNo={}", outTradeNo);

        //千米订单
        TrianRechargeOrder trianRechargeOrder = new TrianRechargeOrder();
        trianRechargeOrder.setOutTradeNo(outTradeNo);
        trianRechargeOrder.setPayResult(BaseAirplaneAndTrianOrder.STATUS_INIT);
        trianRechargeOrder.setPayType(BaseAirplaneAndTrianOrder.PAY_TYPE_ALIPAY);  //火车票在下单时修改一次
        trianRechargeOrder.setTradeNo(response.getTicketTrade().getTradeNo());
        trianRechargeOrder.setState(response.getTicketTrade().getState());
        trianRechargeOrder.setContactTel(contactTel);
        trianRechargeOrder.setContactName(contactName);
        trianRechargeOrder.setPassagers(passagers);
        trianRechargeOrder.setDate(date);
        trianRechargeOrder.setBillState(response.getTicketTrade().getBillState());
        trianRechargeOrder.setStartTime(response.getTicketTrade().getStartTime());
        trianRechargeOrder.setRecevieStation(response.getTicketTrade().getRecevieStation());
        trianRechargeOrder.setStartStation(response.getTicketTrade().getStartStation());
        trianRechargeOrder.setTotalPayCash(response.getTicketTrade().getTotalPayCash());
        trianRechargeOrder.setOrderType(BaseAirplaneAndTrianOrder.TYPE_TRAIN);
        trianRechargeOrder.setTrainNo(response.getTicketTrade().getTrainNo());
        trianRechargeOrder.setOrderCreateTime(new Date());

        //这一步放在下订单时处理，现在是查询。
        trainRechargeOrderRepository.save(trianRechargeOrder);

        //乘客信息 ---实际上，只有预定成功了的才存入数据库。   该步骤应该放在支付那里。
        if (null != response.getTicketTrade()) {
            TrianRechargeOrder rechargeOrder = new TrianRechargeOrder();
            rechargeOrder.setTradeNo(response.getTicketTrade().getTradeNo());
            rechargeOrder.setEndTime(endTime);
            rechargeOrder.setOutTradeNo(outTradeNo);
            rechargeOrder.setTotalPayCash(response.getTicketTrade().getTotalPayCash());
            return rechargeOrder;
        } else {
            throw new UserException(response.getSubMsg(), 303);
        }
    }


    /*
    创建阿里订单
     */
    @Transactional
    public String[] createAlipayOrder(String outTradeNo, long userId) {
        User one = userRepository.findOne(userId);
        if (one == null) {
            throw new UserException("用户不存在", 104);
        }
        String[] res = new String[2];//订单结果
        AlipayOrder alipayOrder = alipayOrderRepository.findByOutTradeNo(outTradeNo);//查询阿里订单
        if (alipayOrder == null) {
            throw new UserException("查询失败", 202);
        }
        wxPayOrderRepository.deleteByOutTradeNo(outTradeNo);
        String payResult = alipayService.pay(alipayOrder);
        if (payResult.equals("fail") || payResult.equals("exception")) {
            res[0] = "fail";
            res[1] = payResult;
            return res;
        }
        res[0] = "success";
        res[1] = alipayService.pay(alipayOrder) + "," + outTradeNo;
        return res;
    }


    /*
    创建微信订单
     */
    @Transactional
    public String[] createWxOrder(String outTradeNo, long userId, String ip) {
        User one = userRepository.findOne(userId);
        if (one == null) {
            throw new UserException("用户不存在", 104);
        }
        String[] res = new String[2];//订单结果
        WxPayOrder order = wxPayOrderRepository.findByOutTradeNo(outTradeNo);
        if (order == null) {
            throw new UserException("查询失败", 202);
        }
        order.setSpbill_create_ip(ip);
        wxPayOrderRepository.save(order);
        alipayOrderRepository.deleteByOutTradeNo(outTradeNo);
        //封装方法，根据外部订单号查找千米的订单类型。
        TrianRechargeOrder trainOrder = trainRechargeOrderRepository.findByOutTradeNo(outTradeNo);
        trainOrder.setPayType(BaseAirplaneAndTrianOrder.PAY_TYPE_WXPAY);
        trainRechargeOrderRepository.save(trainOrder);

        res[0] = "success";
        res[1] = wxPayService.pay(order) + "," + outTradeNo;

        //修改订单状态。
        return res;
    }

    public String pay(String outTradeNo) {
        TrianRechargeOrder order = trainRechargeOrderRepository.findByOutTradeNo(outTradeNo);
        TrainOrderPayRequest request = new TrainOrderPayRequest();
        request.setTradeNo(order.getTradeNo());
        TrainOrderPayResponse response = null;
        try {
            response = publicService.execute(request);
            logger.error("trainResponse ={}", response);
            if (!response.isSuccess()) {
                order.setFailReason(response.getMsg());
                order.setPayResult(BaseAirplaneAndTrianOrder.STATUS_FAIL);
                trainRechargeOrderRepository.save(order);

                if (order.getPayType() == BaseAirplaneAndTrianOrder.PAY_TYPE_ALIPAY) {
                    AlipayOrder byOutTradeNo = alipayOrderRepository.findByOutTradeNo(outTradeNo);
                    byOutTradeNo.setRefundReason(response.getSubMsg());
                    return alipayService.reFund(byOutTradeNo, "");
                } else if (order.getPayType() == BaseAirplaneAndTrianOrder.PAY_TYPE_WXPAY) {
                    WxPayOrder wxPayOrder = wxPayOrderRepository.findByOutTradeNo(outTradeNo);
                    wxPayOrder.setRefundReason(response.getSubMsg());
                    return wxPayService.refund(wxPayOrder, "");
                }
            }
            //付款成功，解析结果，存入数据库。
            publicService.parseTicketsResponse(order.getId(), order.getOutTradeNo(), response.getTicketTrade().getTicketOrders(), Passengers.TYPE_TRAIN,    response.getTicketTrade().getCtime());
            publicService.parseTicketOrderResponse(order, response.getTicketTrade());
            trainRechargeOrderRepository.save(order);
        } catch (ApiException e) {
            if (order.getPayType() == BaseQmOrder.PAY_TYPE_ALIPAY) {
                AlipayOrder byOutTradeNo = alipayOrderRepository.findByOutTradeNo(outTradeNo);
                byOutTradeNo.setRefundReason(e.getMessage());
                return alipayService.reFund(byOutTradeNo, "");
            } else if (order.getPayType() == BaseQmOrder.PAY_TYPE_WXPAY) {
                WxPayOrder wxPayOrder = wxPayOrderRepository.findByOutTradeNo(outTradeNo);
                wxPayOrder.setRefundReason(e.getMessage());
                return wxPayService.refund(wxPayOrder, "");
            }
            e.printStackTrace();
            throw new UserException("付款失败", 202);
        }
        return "error";
    }

    public boolean refund(String orderNos, String refund_free) {
        //根据子订单号找到外部的订单号，然后根据外部订单号找到微信和阿里的订单实体。
        TrainOrderRefundRequest req = new TrainOrderRefundRequest();
        req.setOrderNos(orderNos);
        try {
            TrainOrderRefundResponse response = publicService.execute(req);
            if (response.isSuccess()) {
                if ("1".equals(response.getResult())) {
                    //退票成功,同时要记录到数据库。
                    //同时做退款的处理。检测是微信还是支付宝的退款流程，部分退款流程。
                    for (String pOrder : orderNos.split(",")) {
                        Passengers passenger = passengersRepository.findByOrderNo(pOrder);
                        //得到外部订单号。
                        publicService.refundPay(passenger.getOutTradeNo(), refund_free);
                    }
                    return true;
                }
                //失败做单独处理，重试或者联系客服。记录到数据库。
            }
        } catch (ApiException e) {
            e.printStackTrace();
        }
        return false;
    }

    public List<Passengers> queryTickets(String identityCard) {
        //这里加一层过滤，只显示父订单为成功的显示。
        List<Passengers> passengers = passengersRepository.findAllByIdcardNo(identityCard);
        for (Passengers passenger : new ArrayList<>(passengers)) {
            Long order_id = passenger.getOrder_id();
            //这里要过滤调重复的order_id.
            TrianRechargeOrder one = trainRechargeOrderRepository.findOne(order_id);
//            if (!BaseAirplaneAndTrianOrder.STATUS_SUCCESS.equals(one.getPayResult())) {
//                passengers.remove(passenger);
//            }
        }
        return passengers;
    }
}
